package tagdb.model;

import com.compomics.util.protein.Header;
import tagdb.analysis.ProteinAnalysis;

import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;

/**
 * <b>ProteinHit</b>
 * <p>
 * This class represents an identified protein hit.
 * It contains information about accession, description and a list of containing peptide hits.
 * </p>
 *
 * @author T.Muth
 */
public class ProteinHit {

    /**
     * Protein accession.
     */
    private String accession;

    /**
     * Protein description.
     */
    private String description;

    /**
     * Protein family.
     */
    private String family;

    /**
     * The species of the protein
     */
    private String species;

    /**
     * Peptide hits for the protein.
     */
    private TreeMap<String, PeptideHit> peptideHits;

    /**
     * The amino acid sequence of the protein.
     */
    private String sequence;

    /**
     * The molecular weight.
     */
    private double molWeight = -1;

    /**
     * Constructor for a protein hit.
     *
     * @param header Protein header
     * @param sequence Protein sequence string
     * @param peptideHit Peptide identification hit
     *
     */
    public ProteinHit(Header header, String sequence, PeptideHit peptideHit) {
        this.accession = header.getAccession();
        this.description = header.getDescription();
        this.family = description.substring(0, description.indexOf("_"));
        this.sequence = sequence;
        this.peptideHits = new TreeMap<String, PeptideHit>();
        this.peptideHits.put(peptideHit.getSequence(), peptideHit);
    }

    /**
     * Returns the accession.
     *
     * @return the accession
     */
    public String getAccession() {
        return accession;
    }

    /**
     * Returns the protein family.
     *
     * @return the protein family.
     */
    public String getFamily() {
        return family;
    }

    /**
     * Returns the description.
     *
     * @return the description
     */
    public String getDescription() {
        return description;
    }

    /**
     * Sets the description
     *
     * @param description
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * Returns the species of the protein
     *
     * @return species
     */
    public String getSpecies() {
        return species;
    }

    /**
     * Sets the species of the protein
     *
     * @param species
     */
    public void setSpecies(String species) {
        this.species = species;
    }


    /**
     * Gets the protein's amino acid sequence.
     *
     * @return The protein sequence.
     */
    public String getSequence() {
        return sequence;
    }

    /**
     * Sets the protein's amino acid sequence
     *
     * @param sequence The sequence of the protein.
     */
    public void setSequence(String sequence) {
        this.sequence = sequence;
    }

    /**
     * Returns a list of peptide hits.
     *
     * @return The list of peptide hits.
     */
    public TreeMap<String, PeptideHit> getPeptideHits() {
        return peptideHits;
    }

    /**
     * Returns the peptide hits as list.
     *
     * @return The peptide hits as list.
     */
    public List<PeptideHit> getPeptideHitList() {
        return new ArrayList<PeptideHit>(peptideHits.values());
    }

    /**
     * Sets the list of peptide hits.
     *
     * @param peptideHits The list of peptide hits to set.
     */
    public void setPeptideHits(TreeMap<String, PeptideHit> peptideHits) {
        this.peptideHits = peptideHits;
    }

    /**
     * Adds one peptide to the protein hit.
     *
     * @param peptidehit
     */
    public void addPeptideHit(PeptideHit peptidehit) {
        peptideHits.put(peptidehit.getSequence(), peptidehit);
    }

    /**
     * Convenience method to retrieve a unique peptide hit.
     */
    public PeptideHit getSinglePeptideHit() {
        return peptideHits.firstEntry().getValue();
    }

    /**
     * Returns the calculated molecular protein weight.
     *
     * @return molecular protein weight
     */
    public double getMolWeight() {
        if (molWeight < 0.0) {
            molWeight = ProteinAnalysis.calculateMolecularWeight(this);
        }
        return molWeight;
    }
}
